﻿using ArtMath.Component.Line;
using ArtMath.Component.Point;
using ArtMath.Attribute;
using ArtMath.PointCollection;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Linq;
using System.Text;
using ArtMath.Core.Data;
using ArtMath.Resource;

namespace ArtMath.Component.ConicalSection
{
    /// <summary>
    /// 焦点准线抛物线
    /// </summary>
    [Serializable]
    public class FocusDirectrixParabola : ParabolaBase
    {
        StraightLineBase directrix;
        public FocusDirectrixParabola(SketchPad pad, string name, StraightLineBase zx, bool addToList = true) : base(pad, name, ToolTypeName.jdzxpwx, addToList)
        {
            InPoints = new PointBase[1];
            Directrix = zx;
            OrderIndex = Directrix == null ? 0 : 1;
        }
        [MultilingualCategory("Structure"), MultilingualDisplayName("Focus")]
        public PointBase FocusPoint
        {
            get { return InPoints[0]; }
            set { SetPoint(0, value); }
        }
        [MultilingualCategory("Structure"), MultilingualDisplayName("Directrix"), TypeConverter(typeof(ExpandableObjectConverter))]
        public StraightLineBase Directrix
        {
            get { return directrix; }
            set
            {
                directrix?.OutChildren_Line.Remove(this);
                directrix = value;
                directrix?.OutChildren_Line.Add(this);
            }
        }
        public override PointD Focus
        {
            get
            {
                if (FocusPoint != null) return FocusPoint.ToPointD();
                return base.Focus;
            }
        }
        public override PointD NewFocus
        {
            get
            {
                if (FocusPoint != null) return FocusPoint.NewXY;
                return base.NewFocus;
            }
        }
        public override PointD PFocus
        {
            get
            {
                if (FocusPoint != null) return FocusPoint.Pxy;
                return base.PFocus;
            }
        }
        public override PointD NewPFocus
        {
            get
            {
                if (FocusPoint != null) return FocusPoint.NewPxy;
                return base.NewPFocus;
            }
        }
        public override double NewFocusAngle
        {
            get
            {
                return NewFocus.GetProjectivePoint(Directrix.NewA, Directrix.NewB, Directrix.NewC).GetAngle(NewFocus);
            }
        }
        public override PointD NewCenter
        {
            get
            {
                return (NewFocus.GetProjectivePoint(Directrix.NewA, Directrix.NewB, Directrix.NewC) + NewFocus) / 2;
            }
        }
        public override PointD NewPCenter
        {
            get
            {
                return Pad.XYToPxy(NewCenter);
            }
        }
        public override double NewFocusDirectrixDistance
        {
            get
            {
                return NewFocus.DistanceTo(NewCenter) * 2;
            }
        }
        //public override bool Visible
        //{
        //    get
        //    {
        //        return base.Visible;
        //    }

        //    set
        //    {
        //        base.Visible = value;
        //        if (Directrix != null)
        //        {
        //            Directrix.Visible = Visible;
        //        }
        //    }
        //}
        //public override bool Selected_
        //{
        //    get
        //    {
        //        return base.Selected_;
        //    }

        //    set
        //    {
        //        base.Selected_ = value;
        //        if (Directrix != null)
        //        {
        //            Directrix.Selected_ = Selected_;
        //        }
        //    }
        //}
        //public override StyleState StyleState_
        //{
        //    get
        //    {
        //        return base.StyleState_;
        //    }

        //    set
        //    {
        //        base.StyleState_ = value;
        //        if (Directrix != null)
        //        {
        //            Directrix.StyleState_ = StyleState_;
        //        }
        //    }
        //}
        public override void InChildrenIterator(Predicate<ShapeBase> act)
        {
            if (act == null) return;
            if (Directrix != null)
            {
                if (!act(Directrix)) return;
            }
            base.InChildrenIterator(act);
        }
        //protected override void SetChildrenLinesColor()
        //{
        //    if (Directrix != null)
        //    {
        //        Directrix.LineColor = LineColor;
        //    }
        //    base.SetChildrenLinesColor();
        //}
        //protected override void SetChildrenLinesDashStyle()
        //{
        //    if (Directrix != null)
        //    {
        //        Directrix.LineDashStyle = LineDashStyle;
        //    }
        //    base.SetChildrenLinesDashStyle();
        //}
        //protected override void SetChildrenLinesWidth()
        //{
        //    if (Directrix != null)
        //    {
        //        Directrix.LineWidth.SetExpression(LineWidth.Expression);
        //    }
        //    base.SetChildrenLinesWidth();
        //}
        //public override StraightLineBase[] GetStraightLines()
        //{
        //    return new StraightLineBase[] { Directrix };
        //}
        public override void ComponentBuilding(Base component)
        {
            if (Directrix == null || FocusPoint == null)
            {
                ShowStatus($"{Resources.Translate("Creating")}{Resources.ColonSeparate}{Name}");
                return;
            }
            FocusDirectrixDistance = FocusPoint.ToPointD().DistanceTo(Directrix.A, Directrix.B, Directrix.C);
            PointD proj = FocusPoint.ToPointD().GetProjectivePoint(Directrix.A, Directrix.B, Directrix.C);
            ske.Center = (FocusPoint.ToPointD() + proj) / 2;
            pske.Center = Pad.XYToPxy(Center);
            FocusAngle = proj.GetAngle(FocusPoint.ToPointD());
            base.ComponentBuilding(component);
        }
        //public override void Paint(Graphics gra)
        //{
        //    base.Paint(gra);
        //    if (Directrix != null && Directrix.LayerItem == null)
        //    {
        //        Directrix.Paint(gra);
        //    }
        //}
        public override bool IsCreationCompleted
        {
            get
            {
                return base.IsCreationCompleted && Directrix != null && Directrix.IsCreationCompleted;
            }
        }
        public override bool CanDrawVirtual
        {
            get
            {
                if (OrderIndex == 0)
                {
                    TwoPointsStraightLine sl = Directrix as TwoPointsStraightLine;
                    if (sl != null)
                    {
                        if (sl.Point1 != null)
                        {
                            return true;
                        }
                    }
                    return false;
                }
                else
                {
                    return true;
                }
            }
        }
        public override void CreateComponents()
        {
            if (FocusPoint == null)
            {
                FocusPoint = Pad.CreatePoint(Resources.Translate("Focus"), SpareCoordinate_);
                Pad.TrackObj = this;
                if (Directrix != null)
                {
                    Pad.HostTrackComponentBuilding(FocusPoint.Pxy);
                    base.CreateComponents();
                }
            }
            else
            {
                TwoPointsStraightLine sl;
                if (Directrix == null)
                {
                    sl = new TwoPointsStraightLine(Pad, OfTranslator("Directrix"), false) { SpareCoordinate_ = SpareCoordinate_, };
                    Pad.TrackObj = Directrix = sl;
                    sl.CreateComponents(string.Format("{0}1", Resources.Translate("Point")), new PointCollectionBase[] { new Universal(FocusPoint.ToPointD()) });
                }
                else
                {
                    sl = Directrix as TwoPointsStraightLine;
                    sl.CreateComponents(string.Format("{0}2", Resources.Translate("Point")), new PointCollectionBase[] { new Universal(sl.Point1.ToPointD(), sl.Point1.GetSlope(FocusPoint)) });
                    base.CreateComponents();
                }
            }
        }
    }
}
